﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Text;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.DataManage;
using Labthink.PCSoft.UniversalHost4.Model.Query;
using Labthink.PCSoft.UniversalHost4.Utility;
using NLog;

namespace Labthink.PCSoft.UniversalHost4.DataAccess
{
    public class BackupAndRestore
    {
        private static readonly string RecordPath = Path.Combine(DataManage.BasePath, "Config/BackupAndRestore.dm");
        public static DateTime NextBackupTime;
        public static AutoBackupConfig Config;
        private static readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public static void Init()
        {
            Config = GetConfig();
        }

        public static AutoBackupConfig GetConfig()
        {
            if (!File.Exists(RecordPath)) return null;
            const string sql = "SELECT * FROM Config LIMIT 0,1";
            var ds = SqliteHelper.ExecuteDataSet(RecordPath, sql, null);
            if (ds == null || ds.Tables.Count == 0) return null;
            if (ds.Tables[0].Rows.Count == 0) return null;
            var abc = new AutoBackupConfig
            {
                Frequency = ds.Tables[0].Rows[0][0].ToInt32(),
                Target = ds.Tables[0].Rows[0][1].ToInt32(),
                LocalCount = ds.Tables[0].Rows[0][2].ToInt32()
            };
            abc.AutoBackup = abc.Frequency > 0;
            return abc;
        }

        public static int SetConfig(AutoBackupConfig abc)
        {
            Config = abc;
            _logger.Debug("修改自动备份配置，频率：{0}，目标：{1}", abc.Frequency, abc.Target);
            if (!File.Exists(RecordPath)) return -1;
            try
            {
                var r = SqliteHelper.ExecuteNonQuery(RecordPath, "UPDATE Config SET Frequency=@Frequency,Target=@Target,LocalCount=@LocalCount", abc.AutoBackup ? abc.Frequency : -1, abc.Target, abc.LocalCount);
                return r;
            }
            catch (Exception e)
            {
                _logger.Error(e,"保存自动备份配置失败");
                return -1;
            }
        }

        public static DateTime GetNextBackupTime()
        {
            if (!File.Exists(RecordPath)) return DateTime.MaxValue;
            const string sql = "SELECT BackupTime FROM NextBackupTime";
            var o = SqliteHelper.ExecuteScalar(RecordPath, sql, null);
            if (o != null) return o.ToDateTime();
            return DateTime.MaxValue;
        }

        public static int SetNextBackupTime(DateTime time)
        {
            if (!File.Exists(RecordPath)) return -1;
            NextBackupTime = time;
            try
            {
                var r = SqliteHelper.ExecuteNonQuery(RecordPath, "UPDATE NextBackupTime SET BackupTime=@BackupTime", time);
                return r;
            }
            catch (Exception e)
            {
                _logger.Error(e,"更新下次备份时间失败");
                return -1;
            }
        }

        public static PagedList<DataManageRecord> GetRecords(QueryBase query)
        {
            if (!File.Exists(RecordPath)) return new PagedList<DataManageRecord>();
            _logger.Debug("查询第{0}页{1}条数据操作记录", query.PageIndex, query.PageCount);
            if (query.PageIndex == 0) query.PageIndex = 1;
            var datas = new List<DataManageRecord>();
            if (query.PageIndex <= 0 || query.PageCount <= 0)
            {
                return new PagedList<DataManageRecord>();
            }

            var objs = new List<object>();
            var sqlData = new StringBuilder("SELECT * FROM Record ");
            var sqlCount = new StringBuilder("SELECT COUNT(1) FROM Record ");

            sqlData.Append(" ORDER BY Id DESC LIMIT " + (query.PageIndex - 1) * query.PageCount + "," +
                query.PageCount);
            int count;
            var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(RecordPath));
            con.Open();
            using (var cmd = con.CreateCommand())
            {
                try
                {
                    var reader = SqliteHelper.ExecuteReader(cmd, sqlData.ToString(), objs.ToArray());
                    while (reader.Read())
                    {
                        var ti = new DataManageRecord
                        {
                            Id = reader["Id"].ToInt32(),
                            FileSize = reader["FileSize"].ToDouble(),
                            OperateType = reader["OperateType"].ToInt32(),
                            OperateResult = reader["OperateResult"].ToInt32(),
                            OperateUser = reader["OperateUser"].ToString(),
                            FileName = reader["FileName"].ToString(),
                            Start = reader["Start"].ToDateTime(),
                            End = reader["End"].ToDateTime(),
                        };

                        datas.Add(ti);
                    }

                    reader.Close();
                }
                catch (Exception e)
                {
                    _logger.Error(e,"查询实验记录出错:{0}",  sqlData.ToString());
                    if (con.State != ConnectionState.Closed) con.Close();
                    return null;
                }
            }

            if (con.State != ConnectionState.Open) con.Open();
            try
            {
                count = SqliteHelper.ExecuteScalar(RecordPath, sqlCount.ToString(), objs.ToArray()).ToInt32();
            }
            catch (Exception e)
            {
                _logger.Error(e,"获取数据操作记录总数出错:{0}",  sqlCount.ToString());
                if (con.State != ConnectionState.Closed) con.Close();
                return null;
            }

            if (con.State != ConnectionState.Closed) con.Close();

            return new PagedList<DataManageRecord>(datas)
            {
                TotalCount = count,
                PageIndex = query.PageIndex,
                PageSize = datas.Count,
                PageCount = (int)Math.Ceiling((double)count / query.PageCount)
            };
        }

        public static int AddRecord(DataManageRecord record)
        {
            if (!File.Exists(RecordPath)) return -1;
            _logger.Debug("保存数据操作记录:{0}", record.OperateType);
            var sql =
                @"INSERT INTO Record (
                    FileName,FileSize,OperateType,OperateResult,OperateUser,Start,End) 
                    VALUES (@FileName,@FileSize,@OperateType,@OperateResult,@OperateUser,@Start,@End)";
            var objs = new List<object> {
                record.FileName,record.FileSize,record.OperateType,record.OperateResult,record.OperateUser,record.Start,record.End
            };
            try
            {
                return SqliteHelper.ExecuteNonQuery(RecordPath, sql, objs.ToArray());
            }
            catch (Exception e)
            {
                _logger.Error(e,"保存数据操作记录失败:{0}", e, record.OperateType);
                return -1;
            }
        }

        public static int UpdateRecord(DataManageRecord record)
        {
            if (!File.Exists(RecordPath)) return -1;
            _logger.Debug("更新数据操作记录:{0}", record.OperateType);
            var sql =
                @"UPDATE  Record SET OperateResult=@OperateResult,OperateUser=@OperateUser,Start=@Start,End=@End WHERE Id=@Id";
            var objs = new List<object> { record.OperateResult, record.OperateUser, record.Start, record.End, record.Id };
            try
            {
                return SqliteHelper.ExecuteNonQuery(RecordPath, sql, objs.ToArray());
            }
            catch (Exception e)
            {
                _logger.Error(e,"更新数据操作记录:{0}", e, record.OperateType);
                return -1;
            }
        }
    }
}
